//工具生成，请不要手动修改...
let w: any, r: any, StructCoder: any;
/** 传入k-coder来进行初始化 */
export function initMsg(kcoder: any) {
    w = new kcoder.BinaryWriter();
    r = new kcoder.BinaryReader();
    StructCoder = kcoder.StructCoder;
}

const tosCoderDic: any = {}, tocCoderDic: any = {};
/** 协议消息编解码 */
export const MsgCoder = {

    /** 加载单个协议消息结构 */
    load(msgId: any, struct: any) {
        let st: any;
        tosCoderDic[msgId] = (st = struct[msgId][0]) ? new StructCoder(st()) : undefined;
        tocCoderDic[msgId] = (st = struct[msgId][1]) ? new StructCoder(st()) : undefined;
    },

    /** 加载所有协议消息结构 */
    loadAll(struct: any, onCount?: (count: number) => void) {
        let c = 0;
        for (let msgId in struct) {
            MsgCoder.load(msgId, struct);
            onCount && onCount(++c);
        }
    },

    /** 编码协议消息id */
    encodeMsgId(msgId: MsgId) {
        w.start().uint = msgId;
    },

    /** 编码tos协议消息 */
    encodeTos<ID extends MsgId>(msgId: ID, data: MsgTos<MsgId>): Uint8Array {
        tosCoderDic[msgId]?.encode(data, w);
        return w.end();
    },

    /** 编码toc协议消息 */
    encodeToc<ID extends MsgId>(msgId: ID, data: MsgToc<MsgId>): Uint8Array {
        tocCoderDic[msgId]?.encode(data, w);
        return w.end();
    },

    /** 解码协议消息id */
    decodeMsgId(buf: Uint8Array) {
        return r.start(buf).uint;
    },

    /** 解码tos协议消息 */
    decodeTos<ID extends MsgId>(msgId: ID, buf?: Uint8Array): MsgTos<MsgId> {
        return tosCoderDic[msgId]?.decode(buf || r);
    },

    /** 解码tos协议消息 */
    decodeToc<ID extends MsgId>(msgId: ID, buf?: Uint8Array): MsgToc<MsgId> {
        return tocCoderDic[msgId]?.decode(buf || r);
    },

    /** 解码协议消息id后剩下的buf */
    getMsgBuf() {
        return r.cut(r.len - r.pos);
    }
}

/** 协议号 */
export const enum MsgId {
    xxx = 1111,
    /** 测试协议 */
    test = 1234,
    /** 测试协议2 */
    test2 = 1235,
}

/** 发往服务端的协议消息 */
export type MsgTos<ID extends MsgId> = {
    [MsgId.xxx]: undefined,
    [MsgId.test]: MsgVo.test.tos_test,
    [MsgId.test2]: MsgVo.test.tos_test2,
}[ID]

/** 发往客户端的协议消息 */
export type MsgToc<ID extends MsgId> = {
    [MsgId.xxx]: undefined,
    [MsgId.test]: MsgVo.test.toc_test,
    [MsgId.test2]: MsgVo.test.toc_test2,
}[ID]

/** 协议消息Vo */
export namespace MsgVo {

    export namespace com {

        /** 通用结构 */
        export interface test {
            /** x */
            x: number,
            /** y */
            y: number,
            test2: test2,
        }

        export interface test2 {
            /** x */
            x: number,
            /** y */
            y: number,
            test: test,
        }

    }

    export namespace test {

        export interface test3 {
            a: number[][],
        }

        /** 发服务端协议 */
        export interface tos_test {
            a: number,
            b: number,
            c: number,
            /** 使用通用结构 */
            test: test3,
        }

        /** 发客户端协议 */
        export interface toc_test {
            a: number,
            b: number,
            c: number,
            /** 使用外部通用结构 */
            com: com.test,
        }

        /** 发服务端协议 */
        export interface tos_test2 {
            a: number,
            b: number,
            c: number,
            /** 使用通用结构 */
            test: test3,
        }

        /** 发客户端协议 */
        export interface toc_test2 {
            a: number,
            b: number,
            c: number,
            /** 使用外部通用结构 */
            com: com.test,
        }

    }

}